#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node{
    double d,v,ax;
    int st,en;
}a[100005];
struct point{
    int l=INT_MAX,r=INT_MIN;
}mx[100005];
bool cmp(point x,point y){
    if(x.l==y.l)return x.r>y.r;
    else return x.l<y.l;
}
int t,n,m,ans1,ans2;
double p[100005],mv,len;
signed main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%lf%lf",&n,&m,&len,&mv);
        ans1=n;
        ans2=m;
        for(int i=1;i<=n;i++){
            scanf("%lf%lf%lf",&a[i].d,&a[i].v,&a[i].ax);
        }
        for(int i=1;i<=m;i++){
            scanf("%lf",&p[i]);
        }
        sort(p+1,p+m+1);
        for(int i=1;i<=n;i++){
            if(a[i].ax>0){
                if(a[i].v>mv){
                    a[i].st=lower_bound(p+1,p+m+1,a[i].d)-p;
                    a[i].en=m;
                }
                else{
                    double t=(double)(mv-a[i].v)/(double)(1.0*a[i].ax);
                    double dis=a[i].d+t*a[i].v+a[i].ax*t*t*0.5;
                    if(dis>len){
                        a[i].st=0;
                        a[i].en=0;
                        ans1--;
                    }
                    else{
                        a[i].st=upper_bound(p+1,p+m+1,dis)-p;
                        a[i].en=m;
                    }
                }
            }
            else if(a[i].ax==0){
                if(a[i].v>mv){
                    a[i].st=lower_bound(p+1,p+m+1,a[i].d)-p;
                    a[i].en=m;
                }
                else{
                    a[i].st=0;
                    a[i].en=0;
                    ans1--;
                }
            }
            else{
                if(a[i].v<=mv){
                    a[i].st=0;
                    a[i].en=0;
                    ans1--;
                }
                else{
                    double t=(mv-a[i].v)/a[i].ax;
                    int dis=a[i].d+t*a[i].v+a[i].ax*t*t*0.5-1e-6;
                    if(dis>len){
                        a[i].st=0;
                        a[i].en=0;
                    }
                    else{
                        a[i].st=lower_bound(p+1,p+m+1,a[i].d)-p;
                        a[i].en=upper_bound(p+1,p+m+1,dis)-p-1;
                    }
                }
            }
            if(a[i].st>a[i].en){
                a[i].st=0;
                a[i].en=0;
                ans1--;
            }
        }
        printf("%d ",ans1);
        bool vis[100005];
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            if(a[i].st==0&&a[i].en==0)continue;
            if(!vis[i]){
                vis[i]=true;
                ans2--;
                for(int j=i+1;j<=n;j++){
                    if(a[j].st>a[i].en||a[j].en<a[i].st)continue;
                    vis[j]=true;
                }
            }
        }
        printf("%d\n",ans2);
    }
    return 0;
}
